﻿Imports System.ComponentModel
Imports System.Threading
Imports System.Collections.ObjectModel
Imports System.Text
Imports iConverter.Models
Imports iConverter.Core
Imports iConverter.Commands
Imports iConverter.Extensions

Namespace ViewModels



    Partial Class OptionViewModel



        ''' <summary>
        ''' 注册窗口事件
        ''' </summary>
        ''' <remarks></remarks>
        Private Sub RegisterWindowsEvent()
            AddHandler Me._win.Closing, AddressOf Window_Closing
        End Sub


        ''' <summary>
        ''' 卸载窗口事件
        ''' </summary>
        ''' <remarks></remarks>
        Private Sub UnRegisterWindowsEvent()
            RemoveHandler Me._win.Closing, AddressOf Window_Closing

        End Sub

#Region " 窗口关闭事件"

        Private Sub Window_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)




            If Me.IsChanged AndAlso ShowCloseQuestionMessage() = MessageBoxResult.No Then
                e.Cancel = True
            Else
                e.Cancel = False

                'UnRegisterWindowsEvent()
                Me.Close(True)
            End If

        End Sub

#End Region


        ''' <summary>
        ''' 注册 Command Bindings
        ''' </summary>
        ''' <remarks></remarks>
        Private Sub RegisterCommandBindings()


            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.OKCommand, AddressOf OnExecuteOK, AddressOf OnCanExecuteOK))
            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.CancelCommand, AddressOf OnExecuteCancel, AddressOf OnCanExecuteCancel))
            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.ResetCommand, AddressOf OnExecuteReset, AddressOf OnCanExecuteReset))

            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.PluginConfigCommand, AddressOf OnExecutePluginConfig, AddressOf OnCanExecutePluginConfig))
            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.PluginDisableCommand, AddressOf OnExecutePluginDisable, AddressOf OnCanExecutePluginDisable))
            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.PluginEnableCommand, AddressOf OnExecutePluginEnable, AddressOf OnCanExecutePluginEnable))

            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.MovePostProcessingTopCommand, AddressOf OnExecuteMovePostProcessingTop, AddressOf OnCanExecuteMovePostProcessingTop))
            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.MovePostProcessingUpCommand, AddressOf OnExecuteMovePostProcessingUp, AddressOf OnCanExecuteMovePostProcessingUp))
            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.MovePostProcessingDownCommand, AddressOf OnExecuteMovePostProcessingDown, AddressOf OnCanExecuteMovePostProcessingDown))
            Me._win.CommandBindings.Add(New CommandBinding(OptionCommands.MovePostProcessingBottomCommand, AddressOf OnExecuteMovePostProcessingBottom, AddressOf OnCanExecuteMovePostProcessingBottom))

        End Sub



#Region "插件配置相关"



#Region "PluginDisable 命令"

        Private Sub OnCanExecutePluginDisable(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)

            Dim p = TryCast(e.Parameter, PluginProvider)

            If p IsNot Nothing AndAlso p.IsEnabled Then
                e.CanExecute = True
            Else
                e.CanExecute = False
            End If

            e.Handled = True
        End Sub

        Private Sub OnExecutePluginDisable(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)

            Dim p = TryCast(e.Parameter, PluginProvider)

            If p IsNot Nothing AndAlso p.IsEnabled Then
                PluginsManager.DisablePlugin(p)

                If Me._operatingProvider.ContainsKey(p) AndAlso Me._operatingProvider(p) Then
                    '已经包含，并且上次操作是是 启用 ， 现在禁用等于还原最初的状态
                    Me._operatingProvider.Remove(p)
                Else
                    Me._operatingProvider(p) = False
                End If

            End If

            e.Handled = True
        End Sub

#End Region

        ''' <summary>
        ''' 操作过的插件提供器
        ''' </summary>
        ''' <remarks></remarks>
        Dim _operatingProvider As New Dictionary(Of PluginProvider, Boolean)



#Region "PluginEnable 命令"

        Private Sub OnCanExecutePluginEnable(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
            Dim p = TryCast(e.Parameter, PluginProvider)

            If p IsNot Nothing AndAlso Not p.IsEnabled Then
                e.CanExecute = True
            Else
                e.CanExecute = False
            End If

            e.Handled = True
        End Sub

        Private Sub OnExecutePluginEnable(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
            Dim p = TryCast(e.Parameter, PluginProvider)

            If p IsNot Nothing AndAlso Not p.IsEnabled Then

                PluginsManager.EnablePlugin(p)


                If Me._operatingProvider.ContainsKey(p) AndAlso Not Me._operatingProvider(p) Then
                    '已经包含，并且上次操作是是 禁用 ， 现在启用等于还原最初的状态
                    Me._operatingProvider.Remove(p)
                Else
                    Me._operatingProvider(p) = True
                End If
            End If

            e.Handled = True
        End Sub

#End Region







#Region "PluginConfig 命令"

        Private Sub OnCanExecutePluginConfig(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
            Dim p = TryCast(e.Parameter, PluginProvider)

            If p IsNot Nothing AndAlso p.IsEnabled AndAlso p.CanConfigure Then
                e.CanExecute = True
            Else
                e.CanExecute = False
            End If

            e.Handled = True
        End Sub

        Private Sub OnExecutePluginConfig(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
            Dim p = TryCast(e.Parameter, PluginProvider)

            If p IsNot Nothing AndAlso p.IsEnabled AndAlso p.CanConfigure Then

                PluginSettingsViewModel.ShowPluginSettingsDialog(p)


            End If

            e.Handled = True
        End Sub

#End Region






#Region "MovePostProcessing 命令"

        Private Sub OnCanExecuteMovePostProcessingTop(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)

            Dim para = TryCast(e.Parameter, CheckableItem(Of PostProcessing))

            e.CanExecute = para IsNot Nothing AndAlso Me.PluginPostProcessings.FirstOrDefault IsNot para

            e.Handled = True

        End Sub

        Private Sub OnExecuteMovePostProcessingTop(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)

            Dim para = TryCast(e.Parameter, CheckableItem(Of PostProcessing))

            If para IsNot Nothing AndAlso Me.PluginPostProcessings.FirstOrDefault IsNot para Then
              

                Me.PluginPostProcessings.Remove(para)

                Me.PluginPostProcessings.Insert(0, para)
            End If
            e.Handled = True
        End Sub

#End Region



#Region "MovePostProcessing 命令"

        Private Sub OnCanExecuteMovePostProcessingUp(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)

            Dim para = TryCast(e.Parameter, CheckableItem(Of PostProcessing))

            e.CanExecute = para IsNot Nothing AndAlso Me.PluginPostProcessings.FirstOrDefault IsNot para

            e.Handled = True

        End Sub

        Private Sub OnExecuteMovePostProcessingUp(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)

            Dim para = TryCast(e.Parameter, CheckableItem(Of PostProcessing))

            If para IsNot Nothing AndAlso Me.PluginPostProcessings.FirstOrDefault IsNot para Then
                Dim index = Me.PluginPostProcessings.IndexOf(para)

                Me.PluginPostProcessings.Remove(para)

                Me.PluginPostProcessings.Insert(index - 1, para)
            End If

            e.Handled = True
        End Sub

#End Region



#Region "MovePostProcessing 命令"

        Private Sub OnCanExecuteMovePostProcessingDown(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)

            Dim para = TryCast(e.Parameter, CheckableItem(Of PostProcessing))

            e.CanExecute = para IsNot Nothing AndAlso Me.PluginPostProcessings.LastOrDefault IsNot para
            e.Handled = True

        End Sub

        Private Sub OnExecuteMovePostProcessingDown(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)

            Dim para = TryCast(e.Parameter, CheckableItem(Of PostProcessing))

            If para IsNot Nothing AndAlso Me.PluginPostProcessings.LastOrDefault IsNot para Then
                Dim index = Me.PluginPostProcessings.IndexOf(para)

                Me.PluginPostProcessings.Remove(para)

                Me.PluginPostProcessings.Insert(index + 1, para)
            End If

            e.Handled = True
        End Sub

#End Region


#Region "MovePostProcessing 命令"

        Private Sub OnCanExecuteMovePostProcessingBottom(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)

            Dim para = TryCast(e.Parameter, CheckableItem(Of PostProcessing))

            e.CanExecute = para IsNot Nothing AndAlso Me.PluginPostProcessings.LastOrDefault IsNot para

            e.Handled = True

        End Sub

        Private Sub OnExecuteMovePostProcessingBottom(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)

            Dim para = TryCast(e.Parameter, CheckableItem(Of PostProcessing))

            If para IsNot Nothing AndAlso Me.PluginPostProcessings.LastOrDefault IsNot para Then
                Me.PluginPostProcessings.Remove(para)
                Me.PluginPostProcessings.Add(para)
            End If

            e.Handled = True
        End Sub

#End Region


#End Region




#Region "Reset 命令"

        Private Sub OnCanExecuteReset(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
            e.CanExecute = True
            e.Handled = True
        End Sub

        Private Sub OnExecuteReset(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
            'TODO:修改字符串到资源
            Dim r = MessageBox.Show("你确定要重置所有设置到默认值吗？", "重置", MessageBoxButton.YesNo, MessageBoxImage.Question)

            If r = MessageBoxResult.Yes Then

                SettingManager.Reset()

                MessageBox.Show("重置设置完成！程序将自动退出！请重新启动使设置生效！")

                Me.Close()

                My.Application.Shutdown()

            End If

            e.Handled = True
        End Sub

#End Region



#Region "OK 命令"

        Private Sub OnCanExecuteOK(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
            e.CanExecute = True
            e.Handled = True
        End Sub


        Private Sub OnExecuteOK(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)

            ' 更新设置，并保存

            Update()

            SettingManager.Update(Me.CurrentSettings)

            SettingManager.Save()

            Me.Close()

            e.Handled = True
        End Sub

#End Region





#Region "Cancel 命令"

        Private Sub OnCanExecuteCancel(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
            e.CanExecute = True
            e.Handled = True
        End Sub

        Private Sub OnExecuteCancel(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)

            '取消更新，关闭窗口

            For Each item In Me._operatingProvider
                Dim p = item.Key

                Dim f = item.Value

                If f Then
                    '真代表 ，是开启操作，而原来是禁用， 假相反
                    PluginsManager.DisablePlugin(p)

                Else
                    PluginsManager.EnablePlugin(p)

                End If

            Next

            Me.Close()


            e.Handled = True
        End Sub

        ''' <summary>
        ''' '显示关闭窗口消息
        ''' </summary>
        ''' <returns>MessageBoxResult.No  OR MessageBoxResult.Yes OR MessageBoxResult.None</returns>
        ''' <remarks>
        ''' 如果是用户主动放弃修改，将不会提示问题并返回 None结果
        ''' </remarks>
        Private Function ShowCloseQuestionMessage() As System.Windows.MessageBoxResult
            If Me._isAskClosing Then
                Return MessageBox.Show("程序检测到设置更改，如果继续将会丢失更改。是否要放弃修改？", "设置更改", MessageBoxButton.YesNo, MessageBoxImage.Question)
            Else
                Return MessageBoxResult.None
            End If
        End Function
#End Region






    End Class

End Namespace